package com.ruoyi.common.utils;

import com.ruoyi.common.utils.spring.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
public class LockUtils {

    private static RedisTemplate redisTemplate;

    public static void lock(String key, Long timeoutSecond) {
        while (true) {
            boolean result = getRedisTemplate().opsForValue().setIfAbsent(key, "", timeoutSecond, TimeUnit.SECONDS);
            if (result) {
                return;
            }
            // 无限等待
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                log.error("", e);
            }
        }
    }

    public static boolean tryLock(String key, Long timeoutSecond) {
        long start = System.currentTimeMillis();
        while (true) {
            boolean result = getRedisTemplate().opsForValue().setIfAbsent(key, "", timeoutSecond, TimeUnit.SECONDS);
            if (result) {
                return true;
            }
            //否则循环等待，在timeout时间内仍未获取到锁，则获取失败
            long end = System.currentTimeMillis() - start;
            if (end >= 300) {
                return false;
            }
        }
    }

    public static void unlock(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                getRedisTemplate().delete(key[0]);
            } else {
                getRedisTemplate().delete(CollectionUtils.arrayToList(key));
            }
        }
    }

    public static void unlock(List<String> keys) {
        getRedisTemplate().delete(keys);
    }

    private static RedisTemplate getRedisTemplate() {
        if (redisTemplate == null) {
            redisTemplate = SpringUtils.getBean("redisTemplate");
        }
        return redisTemplate;
    }
}
